package com.aorise.service.diagnosis.impl;

import java.text.SimpleDateFormat;
import java.util.*;

import com.aorise.mapper.camera.AlarmMapper;
import com.aorise.mapper.camera.CameraMapper;
import com.aorise.mapper.diagnosis.*;
import com.aorise.model.camera.AlarmModel;
import com.aorise.service.diagnosis.DiagnosisPlanService;
import com.aorise.utils.EnumType;
import com.aorise.utils.excel.ExcelUtil;
import com.aorise.utils.page.Page;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.aorise.exception.ServiceException;
import com.aorise.model.diagnosis.*;
import com.aorise.service.diagnosis.DiagnosisReportService;
import com.aorise.utils.ConstDefine;
import com.aorise.utils.StatusDefine;
import com.aorise.utils.StatusDefineMessage;

import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;

/**
 * @Author:cat
 * @Desicription: 诊断任务接口服务实现类
 * @Date:Created in 2019-06-26
 * @Modified By:
 */
@Service
public class DiagnosisReportServiceImpl implements DiagnosisReportService {

    @Autowired
    private DiagnosisPlanService diagnosisPlanService;
    @Autowired
    private DiagnosisMQMapper diagnosisMQMapper;
    @Autowired
    private DiagnosisReportMapper diagnosisReportMapper;
    @Autowired
    private ReportCameraMapper reportCameraMapper;
    @Autowired
    private CameraMapper cameraMapper;
    @Autowired
    private AlarmMapper alarmMapper;

    /**
     * @Author:cat
     * @Description 分页查询诊断报告信息
     * @params: map 查询条件
     * @params: page 分页
     * @Date:2019-06-26
     * @Return: List<DiagnosisReportModel> 诊断报告信息集合
     * @Modified By:
     */
    @Override
    public List<DiagnosisReportModel> getAllDiagnosisReportListByPage(Map<String, Object> map, Page page) {
        List<DiagnosisReportModel> diagnosisReportModels = null;

        /**查询总条数*/
        Long count = diagnosisReportMapper.getAllDiagnosisReportListTotalByPage(map);
        if (count > 0) {
            page.setTotalCount(count);
            page.setTotalPage(count, page.getEveryPage());
            if (page.getCurrentPage() > 0 && page.getEveryPage() > 0) {
                /**查询分页条数*/
                diagnosisReportModels = diagnosisReportMapper.getAllDiagnosisReportListByPage(map);
            }
        } else {
            page.setTotalCount(0L);
        }
        return diagnosisReportModels;
    }

    /**
     * @Author:cat
     * @Description 根据ID查询诊断报告详情
     * @params: id 主键ID
     * @Date:2019-06-26
     * @Return: DiagnosisReportModel 诊断报告信息
     * @Modified By:
     */
    @Override
    public DiagnosisReportModel getDiagnosisReportById(Integer id) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("state", ConstDefine.STATE_ABLE);
        return diagnosisReportMapper.getDiagnosisReportById(map);
    }

    /**
     * @Author:cat
     * @Description 分页查询诊断报告明细信息
     * @params: map 查询条件
     * @params: page 分页
     * @Date:2019-06-26
     * @Return: List<ReportCameraModel> 诊断报告明细信息集合
     * @Modified By:
     */
    @Override
    public List<ReportCameraModel> getAllReportCameraListByPage(Map<String, Object> map, Page page) {
        List<ReportCameraModel> reportCameraModels = null;

        /**查询总条数*/
        Long count = reportCameraMapper.getAllReportCameraListTotalByPage(map);
        if (count > 0) {
            page.setTotalCount(count);
            page.setTotalPage(count, page.getEveryPage());
            if (page.getCurrentPage() > 0 && page.getEveryPage() > 0) {
                /**查询分页条数*/
                reportCameraModels = reportCameraMapper.getAllReportCameraListByPage(map);
            }
        } else {
            page.setTotalCount(0L);
        }
        return reportCameraModels;
    }

    /**
     * @Author:cat
     * @Description 导出诊断报告信息
     * @params: map 查询条件
     * @params: response
     * @Date:2019-06-26
     * @Modified By:
     */
    @Override
    public void exportDiagnosisReport(Map<String, Object> map, HttpServletResponse response) {
        List<DiagnosisReportModel> diagnosisReportModels = diagnosisReportMapper.exportDiagnosisReport(map);
        if (diagnosisReportModels.size() > 0) {

            List<String[]> list = new ArrayList<>();
            for (int i = 0; i < diagnosisReportModels.size(); i++) {
                String arr[] = new String[7];
                arr[0] = diagnosisReportModels.get(i).getExecuteTime();
                arr[1] = diagnosisReportModels.get(i).getStartTime() + "-" + diagnosisReportModels.get(i).getEndTime();
                arr[2] = diagnosisReportModels.get(i).getPName();
                arr[3] = diagnosisReportModels.get(i).getCreateUserName();
                arr[4] = diagnosisReportModels.get(i).getCameraSum().toString();
                arr[5] = diagnosisReportModels.get(i).getExceptionSum().toString();
                arr[6] = EnumType.PTYPE.getValue(diagnosisReportModels.get(i).getPType());

                list.add(arr);
            }
            /**导出Excel*/
            ExcelUtil.writeExcel(list, null,7, 3, "诊断报告信息","diagnosis_report_list.xlsx", response);
        }
    }

    /**
     * @Author:cat
     * @Description 导出诊断报告详情信息
     * @params: id 报告ID
     * @params: response
     * @Date:2019-06-26
     * @Modified By:
     */
    @Override
    public void exportReportCamera(Integer id, HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("state", ConstDefine.STATE_ABLE);
        DiagnosisReportModel diagnosisReportModel = diagnosisReportMapper.getDiagnosisReportById(map);
        List<String[]> list = new ArrayList<>();
        Map<String, String> mapReport = new HashMap<>();
        if (diagnosisReportModel != null) {
            mapReport = new HashMap<>();
            mapReport.put("1,1", diagnosisReportModel.getPName());
            mapReport.put("1,3", EnumType.PTYPE.getValue(diagnosisReportModel.getPType()));
            mapReport.put("1,5", diagnosisReportModel.getExecuteTime() + " " + diagnosisReportModel.getStartTime() + "-" + diagnosisReportModel.getEndTime());
            mapReport.put("2,1", diagnosisReportModel.getCreateUserName());
            mapReport.put("2,3", diagnosisReportModel.getCameraSum().toString());
            mapReport.put("2,5", diagnosisReportModel.getExceptionSum().toString());

            if (diagnosisReportModel != null) {

                /**查询诊断报告明细*/
                Map<String, Object> mapM = new HashMap<>();
                mapM.put("reportId", id);
                List<ReportCameraModel> reportCameraModels = reportCameraMapper.getReportCameraByReportId(mapM);
                diagnosisReportModel.setReportCameraModels(reportCameraModels);

                if (reportCameraModels.size() > 0) {

                    list = new ArrayList<>();
                    for (int i = 0; i < reportCameraModels.size(); i++) {
                        String arr[] = new String[6];
                        arr[0] = reportCameraModels.get(i).getCaName();
                        arr[1] = reportCameraModels.get(i).getCaNumber();
                        arr[2] = reportCameraModels.get(i).getIp();
                        arr[3] = reportCameraModels.get(i).getAlarmTime().substring(0, reportCameraModels.get(i).getAlarmTime().length() - 2);
                        arr[4] = reportCameraModels.get(i).getException();
                        arr[5] = reportCameraModels.get(i).getGroupName();

                        list.add(arr);
                    }
                }
            }
        }
        /**导出Excel*/
        ExcelUtil.writeExcel(list, mapReport, 6, 5, "诊断报告详情信息", "report_camera_list.xlsx", response);
    }

    /**
     * @Author:cat
     * @Description 新增诊断报告信息
     * @Date:2019-06-26
     * @Return: Integer 主键
     * @Modified By:
     */
    @Override
    @Transactional
    public Integer addDiagnosisReport() {
        List<DiagnosisMQModel> MQ = diagnosisMQMapper.getDiagnosisMQ();
        if(MQ.size()>0){
            if(MQ.get(0).getStatus() == ConstDefine.DIAGNOSIS_NOT_RUNNING){
                /**任务待执行，先修改状态为执行中*/
                Map<String, Object> mapMQ = new HashMap<>();
                mapMQ.put("id", MQ.get(0).getId());
                mapMQ.put("status", ConstDefine.DIAGNOSIS_RUNNING);
                int iRet = diagnosisMQMapper.updateDiagnosisMQStatus(mapMQ);
                if(iRet>0){
                    /**查询要执行的任务信息*/
                    DiagnosisPlanModel planModel = diagnosisPlanService.getDiagnosisByIdCreateUser(MQ.get(0).getPlanId(),0);
                    if(planModel == null){
                        /**视频诊断计划任务不存在*/
                        throw new ServiceException(
                                StatusDefineMessage.GetMessage(StatusDefine.DIAGNOSIS_REPORT_NOT_HAVE));
                    }

                    /**新增诊断报告*/
                    DiagnosisReportModel diagnosisReportModel = new DiagnosisReportModel();
                    diagnosisReportModel.setPlanId(planModel.getId());
                    diagnosisReportModel.setExecuteTime(GetNowDate("yyyy-MM-dd"));
                    diagnosisReportModel.setStartTime(GetNowDate("HH:mm:ss"));
                    diagnosisReportModel.setEndTime(GetNowDate("HH:mm:ss"));
                    diagnosisReportModel.setPName(planModel.getPName());
                    diagnosisReportModel.setPType(planModel.getPType());
                    diagnosisReportModel.setCameraSum(planModel.getPlanCameraModels().size());
                    diagnosisReportModel.setExceptionSum(planModel.getPlanCameraModels().size());
                    diagnosisReportModel.setCreateUser(planModel.getCreateUser());

                    int iRest = diagnosisReportMapper.addDiagnosisReport(diagnosisReportModel);

                    if(iRest>0) {
                        /**新增诊断报告明细*/
                        for (int i = 0; i < planModel.getPlanCameraModels().size(); i++) {
                            /**随机异常数据*/
                            int randNum = (int) (Math.random() * (12) + 1);

                            ReportCameraModel reportCameraModel = new ReportCameraModel();
                            reportCameraModel.setReportId(diagnosisReportModel.getId());
                            reportCameraModel.setCameraId(planModel.getPlanCameraModels().get(i).getCameraId());
                            reportCameraModel.setCaName(planModel.getPlanCameraModels().get(i).getCaName());
                            reportCameraModel.setCaNumber(planModel.getPlanCameraModels().get(i).getCaNumber());
                            reportCameraModel.setIp(planModel.getPlanCameraModels().get(i).getIp());
                            reportCameraModel.setException(GetRandException(randNum));
                            reportCameraModel.setAlarmTime(GetNowDate("yyyy-MM-dd HH:mm:ss"));
                            reportCameraModel.setGroupName(planModel.getPlanCameraModels().get(i).getGroupName());

                            reportCameraMapper.addReportCamera(reportCameraModel);

                            //TODO: 正常设备删除预警信息，更新设备信息异常状态为正常
                            /**更新智能预警信息，先删除当天该设备的预警信息，再新增*/
                            Map<String, Object> mapA = new HashMap<>();
                            mapA.put("state", ConstDefine.STATE_DISABLE);
                            mapA.put("cameraId", planModel.getPlanCameraModels().get(i).getCameraId());
                            mapA.put("alarmTime", GetNowDate("yyyy-MM-dd"));
                            alarmMapper.deleteAlarm(mapA);

                            AlarmModel alarmModel = new AlarmModel();
                            alarmModel.setCameraId(planModel.getPlanCameraModels().get(i).getCameraId());
                            alarmModel.setCaName(planModel.getPlanCameraModels().get(i).getCaName());
                            alarmModel.setCaNumber(planModel.getPlanCameraModels().get(i).getCaNumber());
                            alarmModel.setIp(planModel.getPlanCameraModels().get(i).getIp());
                            alarmModel.setGroupId(planModel.getPlanCameraModels().get(i).getGroupId());
                            alarmModel.setGroupName(planModel.getPlanCameraModels().get(i).getGroupName());
                            alarmModel.setException(randNum);
                            alarmModel.setAlarmTime(GetNowDate("yyyy-MM-dd HH:mm:ss"));
                            alarmMapper.addAlarm(alarmModel);

                            /**修改设备表异常状态信息*/
                            Map<String, Object> mapC = new HashMap<>();
                            mapC.put("exception", randNum);
                            if (randNum == ConstDefine.OFFLINE) {
                                /**如果异常类型为离线，更新连接状态*/
                                mapC.put("online", ConstDefine.CAMERA_OFFLINE);
                            }else {
                                mapC.put("online", ConstDefine.CAMERA_ONLINE);
                            }
                            mapC.put("id", planModel.getPlanCameraModels().get(i).getCameraId());
                            mapC.put("state", ConstDefine.STATE_ABLE);
                            cameraMapper.updateCameraStatus(mapC);
                        }

                        /**任务执行完毕，删除队列任务*/
                        Map<String, Object> mapMQD = new HashMap<>();
                        mapMQD.put("id", MQ.get(0).getId());
                        return diagnosisMQMapper.deleteDiagnosisMQ(mapMQD);
                    }else
                    {
                        /**新增诊断报告失败*/
                        throw new ServiceException(
                                StatusDefineMessage.GetMessage(StatusDefine.DIAGNOSIS_REPORT_ADD));
                    }
                }else {
                    /**更新队列任务状态失败*/
                    throw new ServiceException(
                            StatusDefineMessage.GetMessage(StatusDefine.DIAGNOSIS_MQ_STATUS_UPDATE));
                }
            }else {
                /**有任务正在执行*/
                return 0;
            }
        }else {
            return 0;
        }
    }


    /**
     * @Author:cat
     * @Description 按指定格式获取当前时间
     * @param formatStr 时间格式
     * @Date:2019-06-26
     * @Return: String 当前时间
     * @Modified By:
     */
    public String GetNowDate(String formatStr){
        String temp_str="";
        Date dt = new Date();

        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        temp_str=sdf.format(dt);
        return temp_str;
    }

    /**
     * @Author:cat
     * @Description 随机获取异常信息
     * @param randNum 异常ID
     * @Date:2019-06-26
     * @Return: String 异常信息
     * @Modified By:
     */
    public String GetRandException(int randNum){
        switch (randNum) {
            case 1:
                return "离线";
            case 2:
                return "图像模糊";
            case 3:
                return "亮度故障";
            case 4:
                return "条纹干扰";
            case 5:
                return "雪花干扰";
            case 6:
                return "画面偏色";
            case 7:
                return "画面冻结";
            case 8:
                return "场景变换";
            case 9:
                return "异物遮挡";
            case 10:
                return "信号缺失";
            case 11:
                return "云镜故障";
            case 12:
                return "标注异常";
            default:
                return "";
        }
    }

}
